package cn.kginglam.dynamic_excel.excel.listener;

import cn.hutool.core.util.StrUtil;
import cn.kginglam.dynamic_excel.common.annotation.NotBlank;
import cn.kginglam.dynamic_excel.common.utils.BeanUtils;
import cn.kginglam.dynamic_excel.common.utils.BitStatesUtils;
import cn.kginglam.dynamic_excel.model.excel.StudentInfoImportModule;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @author: Lam
 * @date: 2021-09-09 17:16
 * @description:
 */
public class StudentInfoImportListener extends AnalysisEventListener<StudentInfoImportModule> {

    /* 全部数据 */
    private List<StudentInfoImportModule> studentInfoImportModuleList = new ArrayList<>();

    /* 校验正确的数据 */
    private List<StudentInfoImportModule> studentInfoImportModuleSuccessList = new ArrayList<>();
    /* 校验错误的数据 */
    private List<StudentInfoImportModule> studentInfoImportModuleErrorList = new ArrayList<>();


    @Override
    public void invoke(StudentInfoImportModule studentInfoImportModule, AnalysisContext analysisContext) {
        // 记录行号
        studentInfoImportModule.setCurrentRowNum(analysisContext.readRowHolder().getRowIndex() + 1);

        // 所有数据必须去除空格
        this.removeBlank(studentInfoImportModule);

        // 属性值校验
        this.valueVerify(studentInfoImportModule);

        // 正确、错误的数据归类
        if(StrUtil.isNotEmpty(studentInfoImportModule.getExceptionInfo())){
            studentInfoImportModuleErrorList.add(studentInfoImportModule);
        }else{
            studentInfoImportModuleSuccessList.add(studentInfoImportModule);
        }

        studentInfoImportModuleList.add(studentInfoImportModule);
    }


    /**
     * 属性值校验
     *
     * @param studentInfoImportModule
     * @return
     */
    private void valueVerify(StudentInfoImportModule studentInfoImportModule) {
        try {
            Field[] fields = studentInfoImportModule.getClass().getDeclaredFields();
            for (Field field : fields) {
                // 可以获取到私有属性
                field.setAccessible(true);

                // 判断带有 @ExcelProperty 注解的属性
                if (!field.isAnnotationPresent(ExcelProperty.class)) {
                    continue;
                }

                Object object = field.get(studentInfoImportModule);

                // 判断当前属性是否带有 @NotBlank && 判断当前值是否为null
                if (field.isAnnotationPresent(NotBlank.class) && Objects.isNull(object)) {
                    this.notBlankVerify(field, studentInfoImportModule);
                }

                // TODO 手机号码的校验 | 证件的校验 | 名字是否正确


            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

    /**
     * 检验必填项是否为空
     * @param field
     * @param studentInfoImportModule
     */
    private void notBlankVerify(Field field, StudentInfoImportModule studentInfoImportModule) {
        // 获取注解备注值
        ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
        String[] value = annotation.value();
        String fieldName = StrUtil.removePrefix(StrUtil.removeSuffix(Arrays.toString(value), "]"), "[");

        // 追加错误信息
        String errorInfo = studentInfoImportModule.getExceptionInfo();
        studentInfoImportModule.setExceptionInfo(StrUtil.isBlank(errorInfo) ? fieldName : errorInfo + "," + fieldName);

        // 追加错误码
        Long exceptionCode = studentInfoImportModule.getExceptionCode();
        studentInfoImportModule.setExceptionCode(BitStatesUtils.addState(exceptionCode, BitStatesUtils.BitStates.FIELD_NULL));
    }

    /**
     * 删除字段空格
     *
     * @param studentInfoImportModule
     */
    private void removeBlank(StudentInfoImportModule studentInfoImportModule) {
        try {
            BeanUtils.removeFieldSpace(studentInfoImportModule);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }


    public List<StudentInfoImportModule> getStudentInfoImportModuleList() {
        return studentInfoImportModuleList;
    }

    public List<StudentInfoImportModule> getStudentInfoImportModuleSuccessList() {
        return studentInfoImportModuleSuccessList;
    }

    public List<StudentInfoImportModule> getStudentInfoImportModuleErrorList() {
        return studentInfoImportModuleErrorList;
    }
}
